home *** CD-ROM | disk | FTP | other *** search
- #!/bin/bash
- ################################################################################
- # #
- # Author: Sean E. Russell <ser@germane-software.com> #
- # Version: 1.0 #
- # Date: Jun 26, 2002 #
- # Adaptation: Mike Frysinger [SpanKY] <vapier@gentoo.org> #
- # Original code was in Ruby ... recoded into bash (at syntax level) #
- # #
- # This application displays information about the RC system used by Gentoo. #
- # In particular, it displays a tree-like format of a run level, showing #
- # all of the services that are installed at that level, and what each #
- # service's status is (running, stopped, etc.) #
- # #
- # -a can be used to display all runlevels #
- # -d can be used to display service dependancies #
- # -u will display all unassigned services #
- # -s will display all services #
- # -h will display help #
- # <runlevel> is used to choose the run level for which information is #
- # displayed #
- # #
- # By default, rc-status only displays information about the current #
- # runlevel; services installed and services running. #
- # #
- ################################################################################
-
- # grab code from functions.sh so we don't have to reproduce it
- source /sbin/functions.sh
- runleveldir=/etc/runlevels
-
- # grab settings from conf.d/rc
- source /etc/conf.d/rc
-
- ################################################################################
- # Parse command line options #
- ################################################################################
- do_opt() {
- case $1 in
- --all|-a)
- ALL=true
- ;;
- --depend)
- DEPEND=true
- ;;
- --unused|-u)
- ALL=true
- UNUSED=true
- ;;
- --list|-l)
- ls -1 ${runleveldir}
- exit 0
- ;;
- --servicelist|-s)
- ALL=true
- SERVICELIST=true
- ;;
- --nocolor|-nc)
- ;;
- --help|-h|-*)
- echo "USAGE: $0 [command | <runlevel>]"
- echo
- echo "Commands:"
- echo " -a, --all Show services at all run levels"
- echo " -l, --list Show list of run levels"
- echo " -u, --unused Show services not assigned to any run level"
- echo " -s, --servicelist Show service list"
- echo " -nc,--nocolor Monochrome output only"
- echo " <runlevel> Show services assigned to <runlevel>"
- echo
- echo "If no arguments are supplied, shows services for current run level."
- exit 0
- ;;
- *)
- runlevel=$1
- ;;
- esac
- }
- for opt in "$@" ; do
- do_opt ${opt}
- [[ -n $2 ]] && shift
- done
-
- ################################################################################
- # Find the current runlevel being queried. This is either something supplied #
- # on the command line, or pulled from softlevel #
- ################################################################################
- if [[ -z "${runlevel}" ]] ; then
- if [[ -e "${svcdir}/softlevel" ]] ; then
- runlevel="$( <${svcdir}/softlevel )"
- else
- ewarn "Could not local current runlevel in ${svcdir}/softlevel"
- if [[ -d "${runleveldir}/single" ]] ; then
- runlevel=single
- elif [[ -d "${runleveldir}/default" ]] ; then
- runlevel=default
- else
- eerror "Your installation is probably broken ... please \`emerge baselayout\`"
- exit 1
- fi
- ewarn "Assuming current runlevel is '${runlevel}'"
- fi
- fi
- if [[ ! -d "${runleveldir}/${runlevel}" ]] ; then
- eerror "${runlevel} is not a valid run level !"
- eerror "Valid runlevels (obtained from \`rc-status --list\`):"
- rc-status --list
- exit 1
- fi
-
- ################################################################################
- # Build up a hash of the services associated with each run level. In the most #
- # trivial case, this is simply the current runlevel. If --all was specified, #
- # we gather information about all of the runlevels. If --unused was #
- # specified, we pull info about all of the services and filter for the ones #
- # that don't appear in any runlevel. #
- ################################################################################
- runlevelidxs=$( ls ${runleveldir} )
- declare -a runlevels
- # For each directory in /etc/runlevels, do ...
- arridx=0
- for level in ${runlevelidxs} ; do
- if [[ ${level} == ${runlevel} || -n ${ALL} ]] ; then
- runlevels[${arridx}]=$( find ${runleveldir}/${level} -maxdepth 1 -type l -printf '%f ' )
- let "arridx += 1"
- fi
- done
-
- # In case --all was specified, get a list of all the services set up in
- # /etc/init.d; services can be added, but not enabled, and we need to
- # identify these 'orphan' services.
- in_list() { #$1=list $2=find
- for ele in $1 ; do
- if [[ ${ele} == $2 ]] ; then
- echo 1
- return 0
- fi
- done
- echo 0
- return 0
- }
- if [[ -n ${ALL} ]] ; then
- unassigned=
- allservices=
- for service in $( ls -1 /etc/init.d | grep -v '\.sh$' ) ; do
- if [[ $( in_list "${runlevels[*]}" "${service}" ) -eq 0 ]] ; then
- unassigned="${unassigned} ${service}"
- fi
- allservices="${allservices} ${service}"
- done
- runlevelidxs="${runlevelidxs} UNASSIGNED"
- runlevels[${arridx}]="${unassigned}"
- runlevels[${arridx}+1]="${allservices}"
- fi
-
- ################################################################################
- # Now collect information about the status of the various services; whether #
- # they're started, broken, or failed. Put all of this into arrays. #
- ################################################################################
- # Read services from ${svcdir}/{started,failed,broken}
- [[ -x "${svcdir}/starting" ]] && starting=$( ls ${svcdir}/starting )
- [[ -x "${svcdir}/inactive" ]] && inactive=$( ls ${svcdir}/inactive )
- [[ -x "${svcdir}/started" ]] && started=$( ls ${svcdir}/started )
- [[ -x "${svcdir}/stopping" ]] && stopping=$( ls ${svcdir}/stopping )
- [[ -x "${svcdir}/failed" ]] && failed=$( ls ${svcdir}/failed )
- [[ -x "${svcdir}/broken" ]] && broken=$( ls ${svcdir}/broken )
-
- ################################################################################
- # Now print out the information we've gathered. We do this by going through #
- # the hash of 'runlevels' information, and for each String key/Array value #
- # pair, print the runlevel; then for each service in that runlevel, print the #
- # service name and its status. #
- ################################################################################
- # Define a helper method for printing the status of a service; '[ xxx ]'
- print_msg() {
- printf " %-$((COLS - 5 - ${#3}))s%s\n" "$1" "${BRACKET}[ $2$3 ${BRACKET}]${NORMAL}"
- }
-
- # if --all wasnt specified, dont print everything
- [[ -z ${ALL} ]] && runlevelidxs=${runlevel}
- if [[ -z ${UNUSED} ]] ; then
- if [[ -z ${SERVICELIST} ]] ; then
- arridx=0
- else
- runlevelidxs="all"
- let "arridx += 1"
- fi
- else
- runlevelidxs="unused"
- fi
-
- for level in ${runlevelidxs} ; do
- echo "Runlevel: ${HILITE}${level}${NORMAL}"
- for service in ${runlevels[${arridx}]} ; do
- if [[ -n ${inactive} && $( in_list "${inactive}" "${service}" ) -eq 1 ]] ; then
- print_msg "${service}" "${WARN}" 'inactive'
- elif [[ $(in_list "${started}" "${service}") -eq 1 ]] ; then
- print_msg "${service}" "${GOOD}" 'started'
- elif [[ -n ${starting} && $( in_list "${starting}" "${service}" ) -eq 1 ]] ; then
- print_msg "${service}" "${GOOD}" 'starting'
- elif [[ -n ${stopping} && $( in_list "${stopping}" "${service}" ) -eq 1 ]] ; then
- print_msg "${service}" "${BAD}" 'stopping'
- elif [[ -n ${failed} && $( in_list "${failed}" "${service}" ) -eq 1 ]] ; then
- print_msg "${service}" "${BAD}" 'failed'
- elif [[ -n ${broken} && $( in_list "${broken}" "${service}" ) -eq 1 ]] ; then
- print_msg "${service}" "${BAD}" 'broken'
- else
- print_msg "${service}" "${WARN}" ' off'
- fi
- done
- let "arridx += 1"
- [ -n "${UNUSED}" ] && exit 0
- done
-